package com.tuxianchao.springbootweblogaspeact.aspeact;

import com.alibaba.fastjson.JSON;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import com.tuxianchao.springbootweblogaspeact.util.IpAddressUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * web层日志切面
 *
 * @author tuxianchao
 * @date 2018/5/12 下午12:02
 */
@Configuration
@Aspect
public class WebControllerAspeact {
    private Logger logger = LoggerFactory.getLogger(WebControllerAspeact.class);

    ThreadLocal<Long> start = new ThreadLocal<>();

    /**
     * pointCut定义
     */
    @Pointcut("execution( * com.tuxianchao.springbootweblogaspeact.controller.*Controller.*(..))")
    public void webLogPointCut() {

    }

    @Before("webLogPointCut()")
    public void before(JoinPoint joinPoint) {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = servletRequestAttributes.getRequest();
        Map<String, String[]> parameterMap = request.getParameterMap();

        Object requestParams = JSON.toJSON(parameterMap);

        String requestUrl = request.getRequestURL().toString();
        String requestUri = request.getRequestURI();
        String requestMethod = request.getMethod();
        String requestIp = IpAddressUtil.getIpAddress(request);

        start.set(System.currentTimeMillis());
        logger.info("请求开始:  startTime:{} ,realip:{} ,url:{} ,uri:{} ,method:{} ,requestParams:{}",
                new Object[]{formatDateTime(start.get()), requestIp, requestUrl, requestUri, requestMethod, requestParams});
    }

    @AfterReturning(returning = "ret", pointcut = "webLogPointCut()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求，返回内容
        long end = System.currentTimeMillis();
        logger.info("请求结束:  endtime:{} ,耗时:{} ,返回值数据length:{} ",
                new Object[]{formatDateTime(end), end - start.get(), ret.toString().length()});
    }

    /**
     * 时间转换
     * <p>
     * System.currentTimeMillis()
     * ==>
     * 2018-05-12 12:55:02 0192
     *
     * @param time
     * @return
     */
    private static String formatDateTime(Long time) {

        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSSS").format(new Date(time));
    }

    public static void main(String[] args) {
        System.out.println(WebControllerAspeact.formatDateTime(System.currentTimeMillis()));
    }
}
